package com.shiyi.principle.demeter;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author qiu
 * @Date 2021-01-15 上午 11:28
 *
 * 迪米特法则：最少知道原则，它表示一个对象应该对其它对象保持最少的了解。通俗来说就是，只与直接的朋友通信。
 * 直接的朋友：每个对象都会与其他对象有耦合关系，只要两个对象之间有耦合关系，我们就说这两个对象之间是朋友关系。
 * 耦合的方式很多，依赖、关联、组合、聚合等。
 * 其中，我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友，而出现在局部变量中的类则不是直接的朋友。
 * 也就是说，陌生的类最好不要作为局部变量的形式出现在类的内部。
 * 对于被依赖的类来说，无论逻辑多么复杂，都尽量的将逻辑封装在类的内部，对外提供 public 方法，不对泄漏任何信息。
 */
public class DemeterTest {

    public static void main(String[] args) {
        MallHeadquarters mallHeadquarters = new MallHeadquarters();
        mallHeadquarters.printSell(new FruitMarket(), new PhoneMarket());
    }

}

/**
 * 商场总部
 */
class MallHeadquarters{

    /**
     * 分析：
     *      属于直接朋友：fruitMarket，phoneMarket
     *      不属于直接朋友：Apple，Phone
     * 迪米特法则中提出陌生的类最好不要以局部变量的形式出现在类的内部，所以该方法不符合迪米特法则。
     * @param fruitMarket 水果市场
     * @param phoneMarket 手机市场
     */
    public void printSell(FruitMarket fruitMarket, PhoneMarket phoneMarket) {
        List<Apple> sellApple = fruitMarket.listSellApple();
        for (Apple apple : sellApple) {
            if (apple.isSell()) {
                System.out.println(apple.getId() + "苹果卖出去了。。。");
            }
        }
        List<Phone> phones = phoneMarket.listSellPhone();
        for (Phone phone : phones) {
            if (phone.isSell()) {
                System.out.println(phone.getId() + "手机卖出去了。。。");
            }
        }
    }
}

/**
 * 水果商场
 */
class FruitMarket {

    public List<Apple> listSellApple() {
        List<Apple> apples = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Apple apple = new Apple();
            apple.setId(i);
            apple.setSell(true);
            apples.add(apple);
        }
        return apples;
    }

}

/**
 * 水果
 */
class Apple {
    /**
     * ID
     */
    private int id;
    /**
     * 是否卖出去了
     */
    private boolean isSell;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public boolean isSell() {
        return isSell;
    }

    public void setSell(boolean sell) {
        isSell = sell;
    }
}

/**
 * 手机商场
 */
class PhoneMarket {

    public List<Phone> listSellPhone() {
        List<Phone> phones = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Phone phone = new Phone();
            phone.setId(i);
            phone.setSell(true);
            phones.add(phone);
        }
        return phones;
    }

}

/**
 * 手机
 */
class Phone {

    /**
     * ID
     */
    private int id;

    /**
     * 是否卖出去了
     */
    private boolean isSell;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public boolean isSell() {
        return isSell;
    }

    public void setSell(boolean sell) {
        isSell = sell;
    }
}
